<?php

namespace StarCloud\Plugins\Shared;

use Phalcon\Di;
use Framework\Library\Validation;
use Phalcon\Validation\Message;
use StarCloud\Library\Exception;

trait Common
{
    public function verifyParamsByRules(array $paramRules)
    {
        $needValidationParamRules = [];
        $requiredOneOf = [];
        foreach ($paramRules as $param => $rule) {
            if (isset($rule['required']) && $rule['required'] === true) {
                if (!$this->hasParam($param)) {
                    Di::getDefault()->get('logger')->info("params error field is:" . $param . ' rule is' . json_encode($rule));
                    throw new Exception('10002', $param . ' is required');
                }
            }

            if (isset($rule['required_together_with']) && is_array($rule['required_together_with'])) {
                if ($this->hasParam($param)) {
                    foreach ($rule['required_together_with'] as $requiredTogetherWithParam) {
                        if (!$this->hasParam($requiredTogetherWithParam)) {
                            Di::getDefault()->get('logger')->info("params error field is:" . $param . ' rule is' . json_encode($rule));
                            throw new Exception('10002', $param . ' is required together with');
                        }
                    }
                }
            }

            if (isset($rule['mutually_exclusive_with']) && is_array($rule['mutually_exclusive_with'])) {
                if ($this->hasParam($param)) {
                    foreach ($rule['mutually_exclusive_with'] as $mutuallyExclusiveWithParam) {
                        if ($this->hasParam($mutuallyExclusiveWithParam)) {
                            Di::getDefault()->get('logger')->info("params error field is:" . $param . ' rule is' . json_encode($rule));
                            throw new Exception('10002', $param . ' is mutually exclusive with');
                        }
                    }
                }
            }

            if (isset($rule['required_one_of']) && $rule['required_one_of'] === true) {
                $requiredOneOf[] = $this->hasParam($param);
            }

            if (isset($rule['default'])) {
                $_REQUEST[$param] = $_REQUEST[$param] ?? $rule['default'];
            }

            if ($this->hasParam($param)) {
                $needValidationParamRules[$param] = $rule;
            }
        }

        if (count($requiredOneOf) != 0 && count(array_filter($requiredOneOf)) == 0) {
            throw new Exception('10002');
        }

        if (!empty($needValidationParamRules)) {
            $validation = new Validation($needValidationParamRules, 'StarCloud\Library\Validator');
            $messages = $validation->validate(array_merge($_REQUEST, $_FILES));
            Di::getDefault()->get('logger')->info("params error message is " . json_encode($needValidationParamRules));
            Di::getDefault()->get('logger')->info("params error message is " . json_encode($messages));

            if (count($messages) != 0) {
                /* @var  $message Message */
                $message = $messages->current();
                throw new Exception('10002', $message->getMessage());
            }
        }
    }

    private function hasParam($param)
    {
        return $this->request->has($param) || isset($_FILES[$param]);
    }
}
